package fr.utbm.tx52.core;

import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.*;

import fr.utbm.MedecinList;
import fr.utbm.PatientList;
import fr.utbm.User;
import fr.utbm.network.IdentificationMessage;
import fr.utbm.network.PatientListMessage;
import fr.utbm.network.SimpleMessage;
import fr.utbm.tx52.database.RetreiveDatas;


public class ClientThread implements Runnable {

	
	/**
	 * Thread du client
	 */
	private Thread _t;
	
	/**
	 * Socket entre le client et le serveur
	 */
	private Socket _socket;
	
	/**
	 * Flux de sortie
	 */
	private ObjectOutputStream _out;
	
	/**
	 * Flux d'entrée
	 */
	private ObjectInputStream _in;
	
	/**
	 * Un lien vers le serveur
	 */
	private Server _server;

	/**
	 * Le nom de la personne connectée, utilisée pour de l'affichage mais n'est pas une donnée critique
	 */
	private String clientName;
	
	
	/**
	 * Identification d'un client via son numéro de téléphone, normalement quand il se connecte
	 * 
	 * @param id
	 * 			L'identifiant du client (son numéro de téléphone)
	 */
	private User connection(IdentificationMessage im)
	{
		System.out.println("Trying to connect : " + im.getLogin());
		
		// TODO Check identification
		User user = RetreiveDatas.getUserFromLogin(im.getLogin(), im.getPassword());
		
		if (user != null) {
			try {
				_out.writeObject(new SimpleMessage("Auth ok"));
			} catch (IOException e) {
				System.out.println("Failed to send handshake");
			}
		}
		else {
			try {
				_out.writeObject(new SimpleMessage("Auth incorrect ! Please retry"));
			} catch (IOException e) {
				System.out.println("Failed to send handshake");
			}
		}
		
		return user;
	}
	

	
	/**
	 * Connexion d'un client
	 * 
	 * @param s
	 * 			La socket utilisée
	 * @param server
	 * 			Un lien vers le serveur
	 */
	ClientThread(Socket s, Server server)
	{
		clientName = "Unknown";
		
		_server = server;
		_socket = s;
		try
		{
			_out = new ObjectOutputStream(_socket.getOutputStream());
			_in = new ObjectInputStream(_socket.getInputStream());
		}
		catch (IOException e){ }

		// on lance le thread du client
		_t = new Thread(this);
		_t.start();
	}

	
	
	/**
	 * Lancement du thread qui va reçevoir les messages
	 */
	public void run()
	{
		try
		{
			User user = null;
			Object message;

			while ( (message = _in.readObject()) != null) {
				
				if ( message instanceof IdentificationMessage) {
					user = connection((IdentificationMessage) message);
				}
				else {
					if (message instanceof PatientListMessage) {
						PatientListMessage plm = (PatientListMessage) message;
						if (plm.getPatientList() == null) {
							PatientList pl = null;
							MedecinList ml = null;
							RetreiveDatas.getDatas(pl, ml, user);
							/*
							System.out.println("Size = " + RetreiveDatas.patients.size());
							System.out.println("Username : " + RetreiveDatas.patients.get(0).getUsername());
							System.out.println("Name : " + RetreiveDatas.patients.get(0).getProfil_nom());
							System.out.println("Lastname : " + RetreiveDatas.patients.get(0).getProfil_prenom());
							*/
							
							//System.out.println("p : " + RetreiveDatas.patients.size());
							plm.setPatientList(RetreiveDatas.patients);
							try {
								_out.writeObject(message);
							} catch (IOException e) {
								System.out.println("Error sending PatientListMsg ");
							}
						}
						else {
							System.out.println("Empty");
						}
					}
					else {
						System.out.println("Received unknown message...");
					}
				}
			}

		}
		catch (Exception e){ 
			System.out.println("Error while receiving message");
		}
		finally // finally se produira le plus souvent lors de la deconnexion du client
		{
			try
			{
				_socket.close(); 
				_server.delClient(this);
			}
			catch (IOException e){ }
		}
	}



	public String getClientName() {
		return clientName;
	}

}
